package leetcode.easy.q38;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Q {
    public static void main(String[] args) {
        long times = System.currentTimeMillis();
//        new Solution().countAndSay(44);
        long time2 = System.currentTimeMillis();
//        new Solution2().countAndSay(44);
        long time3 = System.currentTimeMillis();
        new Solution3().countAndSay(44);
        long time4 = System.currentTimeMillis();
        new Solution4().countAndSay(44);
        long time5 = System.currentTimeMillis();
        log.info("Solution:{},solution2:{},solution3:{},solution4:{}", time2 - times, time3 - time2, time4 - time3, time5 - time4);
    }
}

/**
 * 用stringBuilder构建字符串，方案2的递归版
 */
class Solution4 {
    public String countAndSay(int n) {
        if (n == 1) {
            return "1";
        } else {
            String res = countAndSay(n - 1);
            return countAndSayStr(res);
        }
    }

    private String countAndSayStr(String str) {
        StringBuilder result = new StringBuilder();
        char character = str.charAt(0);
        char cnt = '1';
        int length = str.length();
        for (int i = 1; i < length; i++) {
            char c = str.charAt(i);
            if (c == character) {
                cnt++;
            } else {
                result.append(cnt).append(character);
                character = c;
                cnt = '1';
            }
        }
        return result.append(cnt).append(character).toString();
    }
}

/**
 * 用stringBuilder构建字符串，方案2的递归版
 */
class Solution3 {
    public String countAndSay(int n) {
        if (n == 1) {
            return "1";
        } else {
            String res = countAndSay(n - 1);
            return countAndSayStr(res);
        }
    }

    private String countAndSayStr(String str) {
        StringBuilder result = new StringBuilder();
        char[] chars = str.toCharArray();
        char character = chars[0];
        int cnt = 1;
        for (int i = 1; i < chars.length; i++) {
            char c = chars[i];
            if (c == character) {
                cnt++;
            } else {
                result.append(cnt).append(character);
                character = c;
                cnt = 1;
            }
        }
        return result.append(cnt).append(character).toString();
    }
}

/**
 * 用stringBuilder构建字符串，性能衰减明显优于方案1
 */
class Solution2 {
    public String countAndSay(int n) {
        String str = "1";
        while (--n > 0) {
            str = countAndSayStr(str);
        }
        return str;
    }

    private String countAndSayStr(String str) {
        StringBuilder result = new StringBuilder();
        char[] chars = str.toCharArray();
        char character = chars[0];
        int cnt = 1;
        for (int i = 1; i < chars.length; i++) {
            char c = chars[i];
            if (c == character) {
                cnt++;
            } else {
                result.append(cnt).append(character);
                character = c;
                cnt = 1;
            }
        }
        return result.append(cnt).append(character).toString();
    }
}

/**
 * 直接的字符串拼接，性能极其差，
 */
class Solution {
    public String countAndSay(int n) {
        String str = "1";
        while (--n > 0) {
            str = countAndSayStr(str);
        }
        return str;
    }

    private String countAndSayStr(String str) {
        String result = "";
        char[] chars = str.toCharArray();
        char character = chars[0];
        int cnt = 1;
        for (int i = 1; i < chars.length; i++) {
            char c = chars[i];
            if (c == character) {
                cnt++;
            } else {
                result += cnt + "" + character;
                character = c;
                cnt = 1;
            }
        }
        return result + cnt + "" + character;
    }
}

